package com.danceforyou.order.controller;

import com.danceforyou.common.model.ConfigDO;
import com.danceforyou.common.model.view.BizData4Page;
import com.danceforyou.common.restful.exception.BizExceptionEnum;
import com.danceforyou.common.service.ConfigService;
import com.danceforyou.common.util.AssertUtil;
import com.danceforyou.common.util.Constants;
import com.danceforyou.common.util.ExcelExportUtil;
import com.danceforyou.common.util.StringUtil;
import com.danceforyou.common.vo.OrderExcelVO;
import com.danceforyou.common.vo.SqlOrderEnum;
import com.danceforyou.medium.service.MediumService;
import com.danceforyou.order.model.OrderDO;
import com.danceforyou.order.service.OrderService;
import com.danceforyou.order.vo.OrderVO;
import com.danceforyou.payment.service.PaymentService;
import com.danceforyou.receipt.service.ReceiptService;
import com.danceforyou.user.vo.UserVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.text.SimpleDateFormat;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping(value = "/order")
public class OrderController {

    @Autowired
    private OrderService orderService;
    @Autowired
    private MediumService mediumService;
    @Autowired
    private PaymentService paymentService;
    @Autowired
    private ReceiptService receiptService;
    @Autowired
    private ConfigService configService;
    @Autowired(required = false)
    private HttpSession session;

    private void dealOrderContidion(Map<String, Object> condition) {
        for (Map.Entry<String, Object> entry : condition.entrySet()) {
            if (StringUtil.isBlank(entry.getValue().toString())) {
                condition.put(entry.getKey(), null);
            }
        }
        if (condition.get("numberType") != null) {
            switch (condition.get("numberType").toString()) {
                case "1":
                    //执行价
                    if (condition.get("numberStart") != null) {
                        condition.put("quotedPriceStart", condition.get("numberStart"));
                    }
                    if (condition.get("numberEnd") != null) {
                        condition.put("quotedPriceEnd", condition.get("numberEnd"));
                    }
                    break;
                case "2":
                    //成本价
                    if (condition.get("numberStart") != null) {
                        condition.put("costPriceStart", condition.get("numberStart"));
                    }
                    if (condition.get("numberEnd") != null) {
                        condition.put("costPriceEnd", condition.get("numberEnd"));
                    }
                    break;
                case "3":
                    //客户税点
                    if (condition.get("numberStart") != null) {
                        condition.put("customerPointStart", condition.get("numberStart"));
                    }
                    if (condition.get("numberEnd") != null) {
                        condition.put("customerPointEnd", condition.get("numberEnd"));
                    }
                    break;
                case "4":
                    //客户税额
                    if (condition.get("numberStart") != null) {
                        condition.put("customerTaxStart", condition.get("numberStart"));
                    }
                    if (condition.get("numberEnd") != null) {
                        condition.put("customerTaxEnd", condition.get("numberEnd"));
                    }
                    break;
                case "5":
                    //号主税点
                    if (condition.get("numberStart") != null) {
                        condition.put("mediumPointStart", condition.get("numberStart"));
                    }
                    if (condition.get("numberEnd") != null) {
                        condition.put("mediumPointEnd", condition.get("numberEnd"));
                    }
                    break;
                case "6":
                    //号主税额
                    if (condition.get("numberStart") != null) {
                        condition.put("mediumTaxStart", condition.get("numberStart"));
                    }
                    if (condition.get("numberEnd") != null) {
                        condition.put("mediumTaxEnd", condition.get("numberEnd"));
                    }
                    break;
                case "7":
                    //客户返点
                    if (condition.get("numberStart") != null) {
                        condition.put("customerRebatesStart", condition.get("numberStart"));
                    }
                    if (condition.get("numberEnd") != null) {
                        condition.put("customerRebatesEnd", condition.get("numberEnd"));
                    }
                    break;
                case "8":
                    //号主返点
                    if (condition.get("numberStart") != null) {
                        condition.put("mediumRebatesStart", condition.get("numberStart"));
                    }
                    if (condition.get("numberEnd") != null) {
                        condition.put("mediumRebatesEnd", condition.get("numberEnd"));
                    }
                    break;
                case "9":
                    //利润
                    if (condition.get("numberStart") != null) {
                        condition.put("profitStart", condition.get("numberStart"));
                    }
                    if (condition.get("numberEnd") != null) {
                        condition.put("profitEnd", condition.get("numberEnd"));
                    }
                    break;
                case "10":
                    //利润率
                    if (condition.get("numberStart") != null) {
                        condition.put("profitRateStart", condition.get("numberStart"));
                    }
                    if (condition.get("numberEnd") != null) {
                        condition.put("profitRateEnd", condition.get("numberEnd"));
                    }
                    break;
                default: break;
            }
        }
        if (condition.get("dateType") != null) {
            switch (condition.get("dateType").toString()) {
                case "1":
                    //创建日期
                    if (condition.get("dateStart") != null) {
                        condition.put("create_dateStart", condition.get("dateStart"));
                    }
                    if (condition.get("dateEnd") != null) {
                        condition.put("create_dateEnd", condition.get("dateEnd"));
                    }
                    break;
                case "2":
                    //付款日期
                    if (condition.get("dateStart") != null) {
                        condition.put("payment_dateStart", condition.get("dateStart"));
                    }
                    if (condition.get("dateEnd") != null) {
                        condition.put("payment_dateEnd", condition.get("dateEnd"));
                    }
                    break;
                case "3":
                    //回款日期
                    if (condition.get("dateStart") != null) {
                        condition.put("receipt_dateStart", condition.get("dateStart"));
                    }
                    if (condition.get("dateEnd") != null) {
                        condition.put("receipt_dateEnd", condition.get("dateEnd"));
                    }
                    break;
                case "4":
                    //投放日期
                    if (condition.get("dateStart") != null) {
                        condition.put("putDateStart", condition.get("dateStart"));
                    }
                    if (condition.get("dateEnd") != null) {
                        condition.put("putDateEnd", condition.get("dateEnd"));
                    }
                    break;
                case "5":
                    //结算日期
                    if (condition.get("dateStart") != null) {
                        condition.put("settleDateStart", condition.get("dateStart"));
                    }
                    if (condition.get("dateEnd") != null) {
                        condition.put("settleDateEnd", condition.get("dateEnd"));
                    }
                    break;
                default: break;
            }
        }
        if (condition.get("putAddress") != null && condition.get("putAddress").toString().equals("全部")) {
            condition.remove("putAddress");
        }
        if (condition.get("isPayment") != null && condition.get("isPayment").toString().equals("ALL")) {
            condition.remove("isPayment");
        }
        if (condition.get("isReceipt") != null && condition.get("isReceipt").toString().equals("ALL")) {
            condition.remove("isReceipt");
        }
        if (condition.get("isAdvance") != null && condition.get("isAdvance").toString().equals("ALL")) {
            condition.remove("isAdvance");
        }
        if (condition.get("status") != null && condition.get("status").toString().equals("ALL")) {
            condition.remove("status");
        }
        if (condition.get("mediumUserId") != null && condition.get("mediumUserId").toString().equals("ALL")) {
            condition.remove("mediumUserId");
        }
        if (condition.get("orderUserId") != null && condition.get("orderUserId").toString().equals("ALL")) {
            condition.remove("orderUserId");
        }
    }

    /**
     * 分页查询我的排期列表
     * @param bizData4Page BizData4Page
     * @return BizData4Page
     */
    @RequestMapping(value = "/querySelfOrderPage", method = RequestMethod.GET)
    public BizData4Page<OrderVO> querySelfOrderPage(BizData4Page<OrderVO> bizData4Page) {
        UserVO loginUser = (UserVO) session.getAttribute(Constants.SESSION_USER);
        AssertUtil.notNull(loginUser, BizExceptionEnum.AUTHFAILURE);
        Map<String, Object> condition = bizData4Page.getCondition();
        dealOrderContidion(condition);
        condition.put("createUserId", loginUser.getId());
        condition.put("isDelete", false);
        bizData4Page.setStat(true);
        orderService.queryPageByDataPerm(bizData4Page);
        return bizData4Page;
    }

    /**
     * 分页查询待付款排期列表
     * @param bizData4Page BizData4Page
     * @return BizData4Page
     */
    @RequestMapping(value = "/queryPaymentOrderPage", method = RequestMethod.GET)
    public BizData4Page<OrderVO> queryPaymentOrderPage(BizData4Page<OrderVO> bizData4Page) {
        UserVO loginUser = (UserVO) session.getAttribute(Constants.SESSION_USER);
        AssertUtil.notNull(loginUser, BizExceptionEnum.AUTHFAILURE);
        Map<String, Object> condition = bizData4Page.getCondition();
        dealOrderContidion(condition);
        condition.put("isPayment", false);
        condition.put("isDelete", false);
        if (!loginUser.getRole().getRoleType().equals(Constants.ROLE_GLB_CODE)) {
            condition.put("mediumUserId", loginUser.getId());
        }
        bizData4Page.setStat(true);
        orderService.queryPageByDataPerm(bizData4Page);
        return bizData4Page;
    }

    /**
     * 分页查询待回款排期列表
     * @param bizData4Page BizData4Page
     * @return BizData4Page
     */
    @RequestMapping(value = "/queryReceiptOrderPage", method = RequestMethod.GET)
    public BizData4Page<OrderVO> queryReceiptOrderPage(BizData4Page<OrderVO> bizData4Page) {
        UserVO loginUser = (UserVO) session.getAttribute(Constants.SESSION_USER);
        AssertUtil.notNull(loginUser, BizExceptionEnum.AUTHFAILURE);
        Map<String, Object> condition = bizData4Page.getCondition();
        dealOrderContidion(condition);
        condition.put("isReceipt", false);
        condition.put("isDelete", false);
        if (!loginUser.getRole().getRoleType().equals(Constants.ROLE_GLB_CODE)) {
            condition.put("orderUserId", loginUser.getId());
        }
        bizData4Page.setStat(true);
        orderService.queryPageByDataPerm(bizData4Page);
        return bizData4Page;
    }

    /**
     * 分页查询待结算排期列表
     * @param bizData4Page BizData4Page
     * @return BizData4Page
     */
    @RequestMapping(value = "/querySettleOrderPage", method = RequestMethod.GET)
    public BizData4Page<OrderVO> querySettleOrderPage(BizData4Page<OrderVO> bizData4Page) {
        UserVO loginUser = (UserVO) session.getAttribute(Constants.SESSION_USER);
        AssertUtil.notNull(loginUser, BizExceptionEnum.AUTHFAILURE);
        Map<String, Object> condition = bizData4Page.getCondition();
        dealOrderContidion(condition);
        condition.put("isPayment", true);
        condition.put("isReceipt", true);
        condition.put("isSettle", false);
        condition.put("isDelete", false);
        bizData4Page.setStat(true);
        orderService.queryPageByDataPerm(bizData4Page);
        return bizData4Page;
    }

    /**
     * 分页查询排期统计列表
     * @param bizData4Page BizData4Page
     * @return BizData4Page
     */
    @RequestMapping(value = "/queryStatOrderPage", method = RequestMethod.GET)
    public BizData4Page<OrderVO> queryStatOrderPage(BizData4Page<OrderVO> bizData4Page) {
        UserVO loginUser = (UserVO) session.getAttribute(Constants.SESSION_USER);
        AssertUtil.notNull(loginUser, BizExceptionEnum.AUTHFAILURE);
        Map<String, Object> condition = bizData4Page.getCondition();
        dealOrderContidion(condition);
        condition.put("isDelete", false);
        if (loginUser.getRole().getRoleType().equals(Constants.ROLE_MJB_CODE)) {
            condition.put("mediumUserId", loginUser.getId());
        }
        if (loginUser.getRole().getRoleType().equals(Constants.ROLE_XSB_CODE)) {
            condition.put("orderUserId", loginUser.getId());
        }
        bizData4Page.setStat(true);
        orderService.queryPageByDataPerm(bizData4Page);
        return bizData4Page;
    }

    /**
     * 获取与相似排期条数
     * @param order 排期信息
     * @return Integer
     */
    @RequestMapping(value = "listLikeOrder", method = RequestMethod.GET)
    public Integer listLikeOrder(OrderDO order) {
        UserVO loginUser = (UserVO) session.getAttribute(Constants.SESSION_USER);
        AssertUtil.notNull(loginUser, BizExceptionEnum.AUTHFAILURE);
        return orderService.countByCondition(new HashMap<String, Object>(){{
            put("customerId", order.getCustomerId());
            put("mediumId", order.getMediumId());
            put("quotedPrice", order.getQuotedPrice());
            put("costPrice", order.getCostPrice());
            put("putDate", order.getPutDate());
            put("putAddress", order.getPutAddress());
        }});
    }

    /**
     * 新建排期
     * @param order 排期信息
     * @return boolean
     */
    @RequestMapping(value = "/saveOrderInfo", method = RequestMethod.POST)
    public boolean saveOrderInfo(OrderDO order) {
        orderService.saveInfo(order);
        return true;
    }

    /**
     * 修改排期
     * @param order 排期信息
     * @return boolean
     */
    @RequestMapping(value = "/updateOrderInfo", method = RequestMethod.POST)
    public boolean updateOrderInfo(OrderDO order) {
        orderService.updateInfo(order);
        return true;
    }

    /**
     * 删除排期
     * @param ids 排期IDS
     * @return int
     */
    @RequestMapping(value = "/deleteOrderInfoByIds", method = RequestMethod.POST)
    public int deleteInfoByIds(String ids) {
        return orderService.deleteInfoByIds(ids);
    }

    /**
     * 结算排期
     * @param ids 排期IDS
     * @return int
     */
    @RequestMapping(value = "/setOrderSettle", method = RequestMethod.POST)
    public int setOrderSettle(String ids) {
        return orderService.setOrderSettle(ids);
    }

    /**
     * 获取统计信息
     * @return Map<String, Object>
     */
    @RequestMapping(value = "/getStatInfo", method = RequestMethod.GET)
    public Map<String, Object> getStatInfo() {
        UserVO loginUser = (UserVO) session.getAttribute(Constants.SESSION_USER);
        AssertUtil.notNull(loginUser, BizExceptionEnum.AUTHFAILURE);
        String create_month = DateTimeFormatter.ofPattern("yyyy-MM").format(ZonedDateTime.now());
        Map<String, Object> result = new HashMap<>();
        //统计排期业绩
        Map map = orderService.statOrderInfo(loginUser.getRole().getRoleType(), loginUser.getId(), null);
        result.put("totalOrderProfit", map.get("sumProfit"));
        map = orderService.statOrderInfo(loginUser.getRole().getRoleType(), loginUser.getId(), create_month);
        result.put("monthOrderProfit", map.get("sumProfit"));
        //统计公众号条数
        Map<String, Object> condition = new HashMap<String, Object>(2) {{
            put("status", Constants.MEDIUM_STATUS_ENABLE);
            put("isDelete", 0);
        }};
        result.put("totalMediumCount", mediumService.countByCondition(condition));
        condition.put("createDateStart", create_month + "-01");
        result.put("monthMediumCount", mediumService.countByCondition(condition));
        //统计付款金额
        result.putAll(paymentService.statPaymentInfo(loginUser.getRole().getRoleType(), loginUser.getId()));
        //统计回款金额
        result.putAll(receiptService.statReceiptInfo(loginUser.getRole().getRoleType(), loginUser.getId()));
        return result;
    }

    /**
     * 获取排行榜列表
     * @return List
     */
    @RequestMapping(value = "getRankList", method = RequestMethod.GET)
    public List getRankList() {
        UserVO loginUser = (UserVO) session.getAttribute(Constants.SESSION_USER);
        AssertUtil.notNull(loginUser, BizExceptionEnum.AUTHFAILURE);
        //获取公司配置信息（是否展示排行榜）
        ConfigDO config = configService.getByProperty("configText", Constants.CONFIG_SHOW_RANK);
        if (config != null && "0".equals(config.getConfigValue())) {
            return new ArrayList();
        }
        return orderService.getRankList();
    }

    /**
     * 导出排期信息
     * @param condition 查询条件
     */
    @RequestMapping(value = "/exportStatOrder", method = RequestMethod.GET)
    public void exportStatOrder(@RequestParam Map<String, Object> condition, HttpServletResponse response) {
        UserVO loginUser = (UserVO) session.getAttribute(Constants.SESSION_USER);
        AssertUtil.notNull(loginUser, BizExceptionEnum.AUTHFAILURE);
        dealOrderContidion(condition);
        condition.put("isDelete", false);
        if (loginUser.getRole().getRoleType().equals(Constants.ROLE_MJB_CODE)) {
            condition.put("mediumUserId", loginUser.getId());
        }
        if (loginUser.getRole().getRoleType().equals(Constants.ROLE_XSB_CODE)) {
            condition.put("orderUserId", loginUser.getId());
        }
        List<OrderVO> orderList = orderService.queryList(condition, condition.get("orderBy").toString(), condition.get("sortBy").toString().equals("ASC") ? SqlOrderEnum.ASC : SqlOrderEnum.DESC);
        List<Object> excelVOList = new ArrayList<>();
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        SimpleDateFormat dateTimeFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        for (OrderVO order : orderList) {
            OrderExcelVO excelVO = new OrderExcelVO();
            excelVO.setId(order.getId());
            excelVO.setId(order.getId());
            excelVO.setCustomerBrand(order.getCustomerBrand());
            excelVO.setMediumName(order.getMediumName());
            excelVO.setMediumType(order.getMediumType() == 1 ? "公众号" : "视频号");
            excelVO.setPutDate(dateFormat.format(order.getPutDate()));
            excelVO.setPutAddress(order.getPutAddress());
            excelVO.setQuotedPrice(order.getQuotedPrice());
            excelVO.setCostPrice(order.getCostPrice());
            if (order.getCustomerPoint() < 0) {
                excelVO.setCustomerPoint("普票" + (-order.getCustomerPoint()) + "%");
            } else if (order.getCustomerPoint() == 0) {
                excelVO.setCustomerPoint("不含票");
            } else {
                excelVO.setCustomerPoint("专票" + order.getCustomerPoint() + "%");
            }
            excelVO.setCustomerTax(order.getCustomerTax());
            if (order.getMediumPoint() < 0) {
                excelVO.setMediumPoint("普票" + (-order.getMediumPoint()) + "%");
            } else if (order.getMediumPoint() == 0) {
                excelVO.setMediumPoint("不含票");
            } else {
                excelVO.setMediumPoint("专票" + order.getMediumPoint() + "%");
            }
            excelVO.setMediumTax(order.getMediumTax());
            excelVO.setCustomerRebates(order.getCustomerRebates());
            excelVO.setMediumRebates(order.getMediumRebates());
            excelVO.setProfit(order.getProfit());
            excelVO.setProfitRate(order.getProfitRate() + "%");
            excelVO.setPaymentRate(order.getPaymentRate() + "%");
            excelVO.setReceiptRate(order.getReceiptRate() + "%");
            excelVO.setIsAdvance(order.getIsAdvance() ? "是" : "否");
            excelVO.setMediumUserName(order.getMediumUserName());
            excelVO.setOrderUserName(order.getOrderUserName());
            excelVO.setCreateDate(dateTimeFormat.format(order.getCreateDate()));
            excelVO.setCreateDesc(order.getCreateDesc());
            excelVOList.add(excelVO);
        }
        String[] fieldTitle = {"排期编号", "客户品牌", "媒体名称", "媒体类型", "投放日期", "投放位置", "执行价", "成本价", "客户税点", "客户税额",
                "号主税点", "号主税额", "客户返点", "号主返点", "利润", "利润率", "付款进度", "回款进度", "是否垫付", "对接媒介",
                "对接销售", "创建时间", "创建备注"};
        int[] fieldWidth = {10, 20, 20, 10, 10, 10, 10, 10, 10, 10,
                10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
                10, 20, 40};
        ExcelExportUtil.export("排期列表", fieldTitle, fieldWidth, excelVOList, response);
    }
}
